/*
 *
 *
 *  Created on: 2011/06/09
 *      Author: AKS
 */
#include "core/include/aks_processor.h"
#include "core/include/process.h"
#include "core/include/types.h"

#include "app/subSystem/include/subSystemManager.h"
#include "core/include/aks_string.h"

#include "app/frame_buffer/include/camera_tsk.h"
#include "app/frame_buffer/include/display_tsk.h"
#include "app/usb_host/include/usb_tsk.h"
#include "app/memory/include/mem_tsk.h"

const BYTE MAX_SS_NUM = 8;
SUB_SYSTEM SS_map[8] =
{
    {FALSE, 0xFF, 0xFF},
    {FALSE, 0xFF, 0xFF},
    {FALSE, 0xFF, 0xFF},
    {FALSE, 0xFF, 0xFF},
    {FALSE, 0xFF, 0xFF},
    {FALSE, 0xFF, 0xFF},
    {FALSE, 0xFF, 0xFF},
    {FALSE, 0xFF, 0xFF}
};

BOOL dummyInit(BYTE SS_index);

static const PROCESS_INIT_FUNC initFunctionTable[] =
{
    dummyInit,          // ID = 0 : dummy
    init_camera_tsk,    // ID = 1 : SYS_TYPE_CAMERA_BUFFER
    init_display_tsk,   // ID = 2 : SYS_TYPE_LCD_BUFFER
    init_usb_tsk,       // ID = 3 : SYS_TYPE_USB_HOST
    init_mem_tsk,       // ID = 4 : SYS_TYPE_SRAM
    dummyInit,          // ID = 5 : SYS_TYPE_ETHERNET
};

LIST_ITEM *processItmLst[] =
{
    NULL,               // ID = 0 : dummy
    &cameraItm,         // ID = 1 : SYS_TYPE_CAMERA_BUFFER
    &displayItm,        // ID = 2 : SYS_TYPE_LCD_BUFFER
    &usbItm,            // ID = 3 : SYS_TYPE_USB_HOST
    &memoryItm,        // ID = 4 : SYS_TYPE_SRAM
    NULL,               // ID = 5 : SYS_TYPE_ETHERNET
};

void SS_showDeviceTable(void)
{
	BYTE str[100];
	BYTE *next;

	for(BYTE i=0 ; i<MAX_SS_NUM ; ++i)
	{
		if(TRUE == SS_map[i].installed)
		{
		    next = str;

            next = write_Str((BYTE*)"Device[", next, 100 );
            next = writeUHex( i, next, 100 );
            next = write_Str((BYTE*)"] | type = 0x", next, 100 );
            next = writeUHex( SS_map[i].type, next, 100 );
            next = write_Str((BYTE*)", rev = 0x", next, 100 );
            next = writeUHex( SS_map[i].revision, next, 100 );
            next = write_Str((BYTE*)"\r\n", next, 100 );

            UART_transmitString(UART_DBG, str);
		}
	}

	return;
}

void SUB_SYSTEM_reset(void)
{
    WORD tick = TIMER_systemTick();

    SS_RESET_ASSERT();

    while( TIMER_systemTick() < tick + 20);

    SS_RESET_NEGATE();

}

BOOL SS_enumerate(void)
{
    for(BYTE i=0 ; i<MAX_SS_NUM ; ++i)
    {
    	// for 24LC64F
    	BYTE slaveAdr = SS_BASE_ADDRESS + i;
    	BYTE offset[2] = {0x00, 0x00};
    	BYTE ss_info[16];

    	if(TRUE == I2C_receiveBytes(slaveAdr, offset, 2, ss_info, 16) )
    	{
    		SS_map[i].installed= TRUE;
            SS_map[i].type     = ss_info[SYSTEM_TYPE];
            SS_map[i].revision = ss_info[REVISION];
    	}
    }

    return TRUE;
}

BOOL SS_updateDeviceInformation(BYTE tgt, BYTE *info, BYTE len, WORD offset)
{
	if(len > (64-2))
	{
	    return FALSE;
	}

	BYTE buf[64];
	buf[0] = 0;
	buf[1] = 0;

    for(BYTE i=0 ; i<len ; ++i)
    {
        buf[i+2] = info[i];
    }

	return I2C_transmitBytes(SS_BASE_ADDRESS + tgt, buf, len+2);
}


BOOL dummyInit(BYTE SS_index)
{
	return FALSE;
}

BOOL SS_activateTask(void)
{
    for(BYTE i = 0 ; i < MAX_SS_NUM ; ++i)
    {
        if(TRUE == SS_map[i].installed && SS_map[i].type < sizeof(initFunctionTable))
        {
        	UART_transmitString(UART_DBG, (BYTE*)"install!!!\r\n");
        	if(TRUE == initFunctionTable[(SS_map[i].type)](i))
        	{
        		entryNewProcess(processItmLst[(SS_map[i].type)]);
            }
        	UART_transmitString(UART_DBG, (BYTE*)"finish install!!!\r\n");
        }
    }

    return TRUE;;
}

